# ======================== Inference Backend Configuration ========================
if(NOT DEFINED INFERENCE_BACKEND)
    set(INFERENCE_BACKEND "OPENVINO" CACHE STRING "Select inference backend: CUDA, OPENVINO")
endif()
message(STATUS "Selected inference backend: ${INFERENCE_BACKEND}")

# ======================== Qt Configuration ========================
if(vs_version STREQUAL vs2015)
    set(Qt5_DIR "C:/Qt/5.9.7/msvc2015_64/lib/cmake/Qt5")
	set(Qt5_BIN_DIR C:/Qt/5.9.7/msvc2015_64/bin)
elseif(vs_version STREQUAL vs2019)
    set(Qt5_DIR "C:/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5")
	set(Qt5_BIN_DIR C:/Qt/5.15.2/msvc2019_64/bin)
endif()
find_package(Qt5 COMPONENTS Core Gui Widgets Xml REQUIRED)
message(Qt5Core_INCLUDE_DIRS = ${Qt5Core_INCLUDE_DIRS})

# ======================== Boost Configuration ========================
cmake_policy(SET CMP0074 NEW)
set(Boost_USE_STATIC_RUNTIME ON)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_NO_SYSTEM_PATHS ON)

if(vs_version STREQUAL vs2015)  
    set(BOOST_ROOT ${CMAKE_CURRENT_LIST_DIR}/conan/third-party/common/boost)
elseif(vs_version STREQUAL vs2019)
    set(BOOST_ROOT ${CMAKE_CURRENT_LIST_DIR}/conan/third-party/common_vs2019/boost)
endif()   

if(vs_version STREQUAL vs2015)
    set(BOOST_INCLUDEDIR ${BOOST_ROOT}/include)
    set(BOOST_LIBRARYDIR  ${BOOST_ROOT}/lib64-msvc-14.0)
elseif(vs_version STREQUAL vs2019)
    set(BOOST_INCLUDEDIR ${BOOST_ROOT}/include)
    set(BOOST_LIBRARYDIR  ${BOOST_ROOT}/lib64-msvc-14.2)
endif()

find_package(Boost 1.72.0 REQUIRED COMPONENTS  system filesystem)
if (NOT Boost_FOUND)
    message("NoFound Boost")
else()
    message(STATUS "BOOST_INCLUDEDIR=${BOOST_INCLUDEDIR}")
    message(STATUS "BOOST_LIBRARYDIR=${BOOST_LIBRARYDIR}")
    message(STATUS "Boost_VERSION=${Boost_VERSION}")
endif()

# ======================== OpenCV Configuration ========================
set(MY_OPENCV_DIR ${CMAKE_CURRENT_LIST_DIR}/conan/third-party/common/opencv)
set(MY_OPENCV_INCLUDE_DIR ${MY_OPENCV_DIR}/include)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
	set(MY_OPENCV_LIBS_DIR ${MY_OPENCV_DIR}/debug/lib)
	set(MY_OPENCV_BIN_DIR ${MY_OPENCV_DIR}/debug/bin)
	set(MY_OPENCV_LIBS opencv_cored.lib opencv_highguid.lib opencv_imgcodecsd.lib opencv_imgprocd.lib)
else()
	set(MY_OPENCV_LIBS_DIR ${MY_OPENCV_DIR}/lib)
	set(MY_OPENCV_BIN_DIR ${MY_OPENCV_DIR}/bin)
	set(MY_OPENCV_LIBS opencv_core.lib opencv_highgui.lib opencv_imgcodecs.lib opencv_imgproc.lib)
endif()
message(MY_OPENCV_LIBS = ${MY_OPENCV_LIBS})

# ======================== Crypto++ Configuration ========================
set(MY_CRYPTOPP_DIR ${CMAKE_CURRENT_LIST_DIR}/conan/third-party/common/cryptopp)
set(MY_CRYPTOPP_INCLUDE_DIR ${MY_CRYPTOPP_DIR}/include)
if(CMAKE_BUILD_TYPE AND (CMAKE_BUILD_TYPE STREQUAL "Debug"))
    set(MY_CRYPTOPP_LIB_DIR ${MY_CRYPTOPP_DIR}/lib/debug)
else()
    set(MY_CRYPTOPP_LIB_DIR ${MY_CRYPTOPP_DIR}/lib/release)
endif()
set(MY_CRYPTOPP_BIN_DIR ${MY_CRYPTOPP_LIB_DIR})
set(MY_CRYPTOPP_LIB cryptopp)

# ======================== YAML Configuration ========================
set(MY_YAML_DIR ${CMAKE_CURRENT_LIST_DIR}/conan/third-party/common/yaml-cpp)
if(CMAKE_BUILD_TYPE AND (CMAKE_BUILD_TYPE STREQUAL "Debug"))
    set(MY_YAML_LIB_DIR ${MY_YAML_DIR}/lib/debug)
	set(MY_YAML_BIN_DIR ${MY_YAML_DIR}/bin/debug)
else()
    set(MY_YAML_LIB_DIR ${MY_YAML_DIR}/lib/release)
	set(MY_YAML_BIN_DIR ${MY_YAML_DIR}/bin/release)
endif()
set(MY_YAML_INCLUDE_DIR ${MY_YAML_DIR}/include)
set(MY_YAML_LIB yaml-cpp.lib)

# ======================== pthreads Configuration ========================
set(MY_PTHREADS_DIR ${CMAKE_CURRENT_LIST_DIR}/conan/third-party/common/pthreads)
set(MY_PTHREADS_LIB_DIR ${MY_PTHREADS_DIR}/lib)
set(MY_PTHREADS_INCLUDE_DIR ${MY_PTHREADS_DIR}/include)
set(MY_PTHREADS_LIB pthreadVC2.lib)

# ======================== stb Configuration ========================
set(MY_STB_DIR ${CMAKE_CURRENT_LIST_DIR}/conan/third-party/common/stb)
set(MY_STB_INCLUDE_DIR ${MY_STB_DIR}/include)

if(INFERENCE_BACKEND STREQUAL "CUDA")
    # ======================== CUDA Configuration ========================
    option(CUDA_USE_STATIC_CUDA_RUNTIME OFF)
    
    if (MY_CUDA_VERSION STREQUAL 10.2)
        set(CUDA_TOOLKIT_ROOT_DIR   "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v10.2")
    elseif(MY_CUDA_VERSION STREQUAL 11.1)
        set(CUDA_TOOLKIT_ROOT_DIR   "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.1")
    endif()
    set(CUDAToolkit_ROOT ${CUDA_TOOLKIT_ROOT_DIR})
    set(CMAKE_VS_PLATFORM_TOOLSET_CUDA ${MY_CUDA_VERSION})

    find_package(CUDAToolkit REQUIRED)
    if (CUDAToolkit_FOUND)
        message("CUDAToolkit_VERSION: ${CUDAToolkit_VERSION}")
        message("CUDAToolkit_BIN_DIR: ${CUDAToolkit_BIN_DIR}")
        message("CUDAToolkit_LIBRARY_ROOT: ${CUDAToolkit_LIBRARY_ROOT}")
        message("CUDAToolkit_TARGET_DIR: ${CUDAToolkit_TARGET_DIR}")
        message("CUDAToolkit_NVCC_EXECUTABLE: ${CUDAToolkit_NVCC_EXECUTABLE}")

        set(MY_CUDA_INCLUDE_DIRS ${CUDAToolkit_INCLUDE_DIRS})
        set(MY_CUDA_LIBRARY_DIRS ${CUDAToolkit_LIBRARY_DIRS})
        set(MY_CUDA_LIBRARIES cudart)
    endif()

    # ======================== nvcc flags Configuration ========================
    set(CUDA_NVCC_FLAGS -gencode arch=compute_52,compute_60,compute_61,compute_70,compute_75,code=sm_52,sm_60,sm_61,sm_70,sm_75;-G;-g)
    if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
        set(CMAKE_CUDA_ARCHITECTURES 52 60 61 70 75)
    endif(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)

    # ======================== Cudnn Configuration ========================
    if (MY_CUDA_VERSION STREQUAL 10.2)
        set(MY_CUDNN_DIR ${CMAKE_CURRENT_LIST_DIR}/conan/third-party/cuda10-cudnn8-rt-7/cudnn/cuda)
        set(MY_CUDNN_INCLUDE_DIR ${MY_CUDNN_DIR}/include)
        set(MY_CUDNN_LIB_DIR ${MY_CUDNN_DIR}/lib/x64)
        set(MY_CUDNN_BIN_DIR ${MY_CUDNN_DIR}/bin)
    elseif(MY_CUDA_VERSION STREQUAL 11.1)
        if(MY_TRT_VERSION STREQUAL 7)
            set(MY_CUDNN_DIR ${CMAKE_CURRENT_LIST_DIR}/conan/third-party/cuda11-cudnn8-rt-7/cudnn)
            set(MY_CUDNN_INCLUDE_DIR ${MY_CUDNN_DIR}/include)
            set(MY_CUDNN_LIB_DIR ${MY_CUDNN_DIR}/lib/x64)
            set(MY_CUDNN_BIN_DIR ${MY_CUDNN_DIR}/bin)
        elseif(MY_TRT_VERSION STREQUAL 8)
            set(MY_CUDNN_DIR ${CMAKE_CURRENT_LIST_DIR}/conan/third-party/cuda11-cudnn8-rt-8/cudnn)
            set(MY_CUDNN_INCLUDE_DIR ${MY_CUDNN_DIR}/include)
            set(MY_CUDNN_LIB_DIR ${MY_CUDNN_DIR}/lib)
            set(MY_CUDNN_BIN_DIR ${MY_CUDNN_DIR}/bin)
        else()
            message("MY_TRT_VERSION: ${MY_TRT_VERSION} unsupported")
        endif()
    endif()
    message("MY_CUDNN_DIR: ${MY_CUDNN_DIR}")	
    set(MY_CUDNN_LIB cudnn)

    # ======================== TensorRT Configuration ========================
    if (MY_CUDA_VERSION STREQUAL 10.2)
        set(MY_TRT_DIR ${CMAKE_CURRENT_LIST_DIR}/conan/third-party/cuda10-cudnn8-rt-7/tensorrt/TensorRT-7.2.2.3)
    elseif(MY_CUDA_VERSION STREQUAL 11.1)
        if(MY_TRT_VERSION STREQUAL 7)
            set(MY_TRT_DIR ${CMAKE_CURRENT_LIST_DIR}/conan/third-party/cuda11-cudnn8-rt-7/tensorrt)
        elseif(MY_TRT_VERSION STREQUAL 8)
            set(MY_TRT_DIR ${CMAKE_CURRENT_LIST_DIR}/conan/third-party/cuda11-cudnn8-rt-8/tensorrt)
        else()
            message("MY_TRT_VERSION: ${MY_TRT_VERSION} unsupported")
        endif()
    endif()
    set(MY_TRT_INCLUDE_DIR ${MY_TRT_DIR}/include)
    set(MY_TRT_LIB_DIR ${MY_TRT_DIR}/lib)
    set(MY_TRT_BIN_DIR ${MY_TRT_DIR}/lib)
    set(MY_TRT_LIBS nvinfer nvonnxparser)
    message("MY_TRT_DIR: ${MY_TRT_DIR}")	

elseif(INFERENCE_BACKEND STREQUAL "OPENVINO")
    # ======================== OpenVINO Configuration ========================
    set(MY_OPENVINO_DIR "D:/w_openvino_toolkit_windows_2024.3.0.16041.1e3b88e4e3f_x86_64/runtime")
    set(MY_OPENVINO_INCLUDE_DIR ${MY_OPENVINO_DIR}/include)
    if(CMAKE_BUILD_TYPE AND (CMAKE_BUILD_TYPE STREQUAL "Debug"))
        set(MY_OPENVINO_LIB_DIR ${MY_OPENVINO_DIR}/lib/intel64/Debug)
        set(MY_OPENVINO_BIN_DIR ${MY_OPENVINO_DIR}/bin/intel64/Debug)
    else()
        set(MY_OPENVINO_LIB_DIR ${MY_OPENVINO_DIR}/lib/intel64/Release)
        set(MY_OPENVINO_BIN_DIR ${MY_OPENVINO_DIR}/bin/intel64/Release)
    endif()
    set(MY_OPENVINO_LIBS ${MY_OPENVINO_LIB_DIR}/openvino.lib)
    message(MY_OPENVINO_LIBS = ${MY_OPENVINO_LIBS})

    # ======================== IPP Configuration ========================
    set(MY_IPP_DIR "D:/w_oneapi_2024.0.1.46/ipp")
    set(MY_IPP_INCLUDE_DIR ${MY_IPP_DIR}/latest/include)
    if(CMAKE_BUILD_TYPE AND (CMAKE_BUILD_TYPE STREQUAL "Debug"))
        set(MY_IPP_LIB_DIR ${MY_IPP_DIR}/latest/lib/intel64)
        set(MY_IPP_BIN_DIR ${MY_IPP_DIR}/latest/redist/intel64)
    else()
        set(MY_IPP_LIB_DIR ${MY_IPP_DIR}/latest/lib/intel64)
        set(MY_IPP_BIN_DIR ${MY_IPP_DIR}/latest/redist/intel64)
    endif()
    set(MY_IPP_LIBS 
        ${MY_IPP_LIB_DIR}/ippcc.lib
        ${MY_IPP_LIB_DIR}/ippch.lib
        ${MY_IPP_LIB_DIR}/ippcv.lib
        ${MY_IPP_LIB_DIR}/ippdc.lib
        ${MY_IPP_LIB_DIR}/ippe.lib
        ${MY_IPP_LIB_DIR}/ippi.lib
        ${MY_IPP_LIB_DIR}/ipps.lib
        ${MY_IPP_LIB_DIR}/ippvm.lib
        ${MY_IPP_LIB_DIR}/ippcore.lib
    )
    message(MY_IPP_LIBS = ${MY_IPP_LIBS})
endif()
